package com.cac.demo.service.CallInterface;

import com.cac.demo.dao.CallInterFace.CallInterFaceDao;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;


/**
 * @param //code       接口表中存储的业务接口编码，格式为字符串
 * @param //name       接口表中存储的业务接口名称，格式为字符串
 * @param //parameters 业务接口所需参数，格式为字符串，如果接口请求方式为GET，参数必须为Json字符串
 * @return Entity
 * @Title: callInterface
 * @Description: 接口调用，传入接口表中存储的接口code和所需参数，当前方法将查询code值对应的业务接口地址完成调用，并生成接口调用日志
 */
@Slf4j
@Service
public class CallInterfaceService {
    @Autowired
    private CallInterFaceDao callInterFaceDao;
    @Autowired
    private Environment environment;

    //将要发的数据打包
    public HashMap getMatchData(Map map) {
        long starttime = System.currentTimeMillis();
        //方法返回数据对象
        HashMap resul = new HashMap();
        System.out.println("map1111111111111:" + map);

        String debugModel = environment.getProperty("pathProperty.debug");

        if ("true".equals(debugModel)) {
            resul.put("retCode", "200");
            return (resul);
        }

        String code = (String) map.get("code");
        String name = (String) map.get("name");
        String parameters = JSON.toJSONString(map.get("parameters"));
        System.out.println(parameters + "<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

        // 接口url
        String url = null;
        // 接口请求方式
        String method = null;
        // 接口请求头
        String headers = null;
        Map<String, String> headersMap = null;
        // 接口请求参数，请求方式为get时，传入参数需要为JSON格式，方便将参数转为键值对
        Map<String, Object> parametersMap = null;

        // 数据库持久化操作对象
        //PersistenceService persistenceService = DatabaseHelper.getInstance().getPersistenceService();
        System.out.println(code + "code>>>>>>>>>>>>>>>>>>>>>>>>>>");
        HashMap interfaceMap = callInterFaceDao.getInterface(code);
        System.out.println(interfaceMap + "000000000000000000000000000000");
        // 查询接口
        //Map<String, Object> interfaceMap = null;
        try {
            if ("".equals(code) || "".equals(name) || "".equals(parameters)) {
                resul.put("retCode", "201");
                resul.put("message", "接口调用参数为空！");
                return resul;
            }
//            Map<String, Object> interfaceParam = new HashMap<String, Object>();
//            interfaceParam.put("code", code);
//            interfaceParam.put("name", name);
            if (interfaceMap.isEmpty()) {
                resul.put("retCode", "201");
                String message = "未查询到业务接口【" + name + "】，无法调用接口！";
                resul.put("message", message);
                return resul;
            }
        } catch (Exception e) {
            resul.put("retCode", "201");
            String message = "查询业务接口【" + name + "】失败！失败原因：" + e.getMessage();
            resul.put("message", message);
            return resul;
        }


        // 参数处理
        try {
            url = interfaceMap.get("url").toString();
            method = interfaceMap.get("request_method").toString();
            // 目前仅支持GET和POST调用
            if (!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("POST")) {
                resul.put("retCode", "201");
                String message = "\"目前业务接口调用仅支持GET和POST方式！\"";
                resul.put("message", message);
                return resul;
            }
            headers = interfaceMap.get("request_headers").toString();
            headersMap = (Map<String, String>) JSONObject.parse(headers);
            // get方式调用m
            if (method.equalsIgnoreCase("GET")) {
                //parametersMap = JSONObject.parseObject(parameters, Map.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resul.put("retCode", "201");
            String message = "业务接口【" + name + "】，调用参数处理失败！失败原因：" + e.getMessage();
            resul.put("message", message);
            return resul;
        }
        // 开始请求接口
        String result = null;
        if (method.equalsIgnoreCase("GET")) {
            result = HttpUtil.createGet(url)
                    .addHeaders(headersMap)
                    .form(parametersMap)
                    .charset("UTF-8")
                    .timeout(30000)
                    .setReadTimeout(1000*60*10)
                    .execute()
                    .body();
        } else {
            result = HttpUtil.createPost(url)
                    .addHeaders(headersMap)
                    .body(parameters)
                    .charset("UTF-8")
                    .timeout(30000)
                    .setReadTimeout(1000*60*10)
                    .execute()
                    .body();
        }
        System.out.println(result);

        //文件打包调用网闸所需参数，文件路径、文件名
        JSONObject json = (JSONObject) JSON.parse(result);
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>" + json.toJSONString());
        String filePath = json.getJSONObject("data").getString("matchData");
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>" + filePath);
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>" + filePath.lastIndexOf("/"));
        String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length());
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>" + fileName);
        resul.put("filePath", filePath);
        resul.put("fileName", fileName);
        resul.put("retCode", "200");
        resul.put("result", result);
        resul.put("message", "成功");
        long endtime = System.currentTimeMillis();
        resul.put("packFileTime",(endtime-starttime)/1000);
        return resul;
    }

    //将打包的数据上传"发送文件"
    public HashMap sendFile(String code, String name, String parameters) {
        HashMap entity = new HashMap();

        String debugModel = environment.getProperty("pathProperty.debug");

        if ("true".equals(debugModel)) {
            entity.put("retCode", "200");
            return entity;
        }
        Map<String, Object> parametersMap = null;
        HashMap interfaceMap = callInterFaceDao.getInterface(code);
        // 接口url
        String url = null;
        // 接口请求方式
        String method = null;
        // 接口请求头
        String headers = null;
        Map headersMap;
        try {
//            Map<String, Object> interfaceParam = new HashMap<String, Object>();
//            interfaceParam.put("code", code);
//            interfaceParam.put("name", name);
            if (interfaceMap.isEmpty()) {
                entity.put("retCode", "200");
                entity.put("message", "未查询到业务接口【" + name + "】，无法调用接口！");
                return entity;
            }
        } catch (Exception e) {
            entity.put("retCode", "201");
            entity.put("message", "查询业务接口【" + name + "】失败！失败原因：" + e.getMessage());
            return entity;
        }
        // 参数处理
        try {
            url = interfaceMap.get("url").toString();
            method = interfaceMap.get("request_method").toString();
            // 目前仅支持GET和POST调用
            if (!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("POST")) {
                entity.put("retCode", "201");
                entity.put("message", "目前业务接口调用仅支持GET和POST方式！");
                return entity;
            }
            headers = interfaceMap.get("request_headers").toString();
            headersMap = (Map<String, String>) JSONObject.parse(headers);
            // get方式调用m
            if (method.equalsIgnoreCase("GET")) {
//                parametersMap = JSONObject.parseObject(parameters, Map.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            entity.put("retCode", "201");
            entity.put("message", "业务接口【" + name + "】，调用参数处理失败！失败原因：" + e.getMessage());
            return entity;
        }
        /*{
                "url":"网闸另一端第三方业务系统的数据接收接口url，必选",
                "sendSys":"发送方业务系统名称，必选",3-14新增
	        	"sendScenario":"发送方业务场景名称，必选",3-14新增
	        	"targetSys":"网闸另一端第三方业务系统的名称，必选",3-14新增
                "header":"网闸另一端第三方业务系统的数据接收接口请求头，可以不选",
                "BData":"通过Base64加密的自定义业务数据字符串，可以不选，如果发送文件的同时，希望发送自定义业务数据，可选",
                "files":"文件数组，内容为可访问的文件链接，必选",
                "sendMeta":"是否向网闸另一端第三方业务系统的数据接收接口转发网闸的元数据，
                             由第三方业务系统自己根据网闸的接口文档去下载文件，可以不选，布尔值，默认false",
                "auditMap":"网闸需要的审核数据，一般情况下必选，也可以不选，使用默认审核数据"
        }*/
        // HashMap interfaceMap2 = callInterFaceDao.getInterface("sendMesUrl");

        System.out.println("=====================parameters==========:" + parameters);

        // 开始请求接口
        String result = null;
        if (method.equalsIgnoreCase("GET")) {
            result = HttpUtil.createGet(url)
                    .addHeaders(headersMap)
                    .form(parameters)
                    .charset("UTF-8")
                    .timeout(30000)
                    .setReadTimeout(1000*60*10)
                    .execute()
                    .body();
        } else {
            result = HttpUtil.createPost(url)
                    .addHeaders(headersMap)
                    .body(parameters)
                    .charset("UTF-8")
                    .timeout(30000)
                    .setReadTimeout(1000*60*10)
                    .execute()
                    .body();
        }
        System.out.println("=====================文件result:" + result);
        entity.put("retCode", "200");
        entity.put("message", result);
        return entity;
    }

    //业务数据加密
    public static String encodeBData(String jsonStr) {
        String reult = "";
        //对已经转换成字符串的数据进行加密
        try {
            Base64.Encoder encoder = Base64.getEncoder();
            reult = encoder.encodeToString(jsonStr.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return reult;
    }

    //将打包的数据上传
    public HashMap sendBData(String code, String name, String BData, String sendScenario) {

        HashMap entity = new HashMap();
        String debugModel = environment.getProperty("pathProperty.debug");
        if ("true".equals(debugModel)) {
            entity.put("retCode", "200");
            return entity;
        }
        Map<String, Object> parametersMap = null;

        HashMap interfaceMap = callInterFaceDao.getInterface(code);
        // 接口url
        String url = null;
        // 接口请求方式
        String method = null;
        // 接口请求头
        String headers = null;

        Map headersMap = new HashMap();
        if (interfaceMap == null || interfaceMap.isEmpty()) {
            entity.put("retCode", "201");
            entity.put("message", "未查询到业务接口【" + name + "】，无法调用接口！");
            return entity;
        }
        // 参数处理
        try {
            url = interfaceMap.get("url").toString();
            method = interfaceMap.get("request_method").toString();
            // 目前仅支持GET和POST调用
            if (!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("POST")) {
                entity.put("retCode", "201");
                entity.put("message", "目前业务接口调用仅支持GET和POST方式！");
                return entity;
            }
            headers = interfaceMap.get("request_headers").toString();
            headersMap = (Map<String, String>) JSONObject.parse(headers);
            // get方式调用m
            if (method.equalsIgnoreCase("GET")) {
//                parametersMap = JSONObject.parseObject(parameters, Map.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            entity.put("retCode", "201");
            entity.put("message", "业务接口【" + name + "】，调用参数处理失败！失败原因：" + e.getMessage());
            return entity;
        }
        String parameters = "";
        /*{
            "url":"网闸另一端第三方业务系统的数据接收接口url，必选",
                "sendSys":"发送方业务系统名称，必选",3-14新增
	        	"sendScenario":"发送方业务场景名称，必选",3-14新增
	        	"targetSys":"网闸另一端第三方业务系统的名称，必选",3-14新增
                "method":"网闸另一端第三方业务系统的数据接收接口请求方式，GET|POST|PUT|DELETE，必选",
                "header":"网闸另一端第三方业务系统的数据接收接口请求头，可以不选",
                "BData":"通过Base64加密的自定义业务数据字符串，必选",
                "auditMap":"网闸需要的审核数据，一般情况下必选，也可以不选，使用默认审核数据"
        }*/
        //调用网闸所需参数组装
        JSONObject tmp = new JSONObject();
        String url2 = environment.getProperty("pathProperty.url");
        tmp.put("url", url2);
        tmp.put("method", method);
        tmp.put("BData", BData);
        tmp.put("sendSys", "分拣系统");
        tmp.put("targetSys", "MES系统");
        tmp.put("sendScenario", sendScenario);
        parameters = tmp.toJSONString();

        // 开始请求接口
        String result = null;
        try {
            if (method.equalsIgnoreCase("GET")) {
                result = HttpUtil.createGet(url)
                        .addHeaders(headersMap)
                        .form(parametersMap)
                        .charset("UTF-8")
                        .timeout(30000)
                        .execute()
                        .body();
            } else {
                result = HttpUtil.createPost(url)
                        .addHeaders(headersMap)
                        .body(parameters)
                        .charset("UTF-8")
                        .timeout(30000)
                        .execute()
                        .body();
            }
            System.out.println("=====================业务数据result:" + result);
            entity.put("retCode", "200");
            entity.put("message", result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return entity;
    }

}


